# This Python file uses the following encoding: utf-8
# ##############################################################################
# Copyright (c) 2025 Li Auto Inc. and its affiliates
# Licensed under the Apache License, Version 2.0(the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ##############################################################################
"""
CanTrcv1145配置代码生成模块.
"""
from func_module.health_monitor.logger import logger

spiChannel_sorted_dict = {}
spiJob_sorted_dict = {}
spiSequence_sorted_dict = {}

spiChannel_sorted_index_dict = {}
spiJob_sorted_index_dict = {}
spiSequence_sorted_index_dict = {}

baudrate_bin2dec_dict = {
    '0b000': 50, \
    '0b001': 100, \
    '0b010': 125, \
    '0b011': 250, \
    '0b101': 500, \
    '0b111': 1000
    }

baudrate_dec2bin_dict = {
    50: '0b000', \
    100: '0b001', \
    125: '0b010', \
    250: '0b011', \
    500: '0b101', \
    1000: '0b111'
    }

# 获取 uint32变量 的第一个字节（最高位字节，即最左边）
def getFirstByteOfUint32Var(var) -> int:
    var = (var >> 24) & 0xFF
    return int(var)

# 获取 uint32变量 的第二个字节
def getSecondByteOfUint32Var(var) -> int:
    var = (var >> 16) & 0xFF
    return int(var)

# 获取 uint32变量 的第三个字节
def getThirdByteOfUint32Var(var) -> int:
    var = (var >> 8) & 0xFF
    return int(var)

# 获取 uint32变量 的第四个字节
def getForthByteOfUint32Var(var) -> int:
    var = var & 0xFF
    return int(var)

def change_boolean(b: bool) -> str:
    if b == True:
        return "STD_ON"
    else:
        return "STD_OFF"


def get_name(key_name: str) -> str:
    key_name = key_name.split("/")[-1]
    return key_name

def checkIsNotNone(input):
    return (input is not None) and (input != "") and (input != "<empty>") and (input != "None")

def get_spi_prefix(sys_config: dict):
    spi_channel_prefix = "SpiConf_SpiChannel_"
    spi_sequence_prefix = "SpiConf_SpiSequence_"
    cur_platform = sys_config["target"]
    if cur_platform == "J6E":
        spi_channel_prefix = "SpiConf_"
        spi_sequence_prefix = "SpiConf_"
    return spi_channel_prefix, spi_sequence_prefix
def get_template_input_parameter_dict(sys_config: dict, input_dict: dict) -> dict:
    CanTrcv1145_config_dict = {}
    Spi_config_dict = {}

    CanTrcv1145_Genernal_dict = {}
    CanTrcv1145_ConfigSet_dict = {}

    try:
        CanTrcv1145_config_dict = input_dict["bsw"]["cantrcv1145"]["ArPackages"]["ActiveEcuC"]["CanTrcv1145"]
    except KeyError:
        logger.warning("CanTrcv1145 Config is not exist. VCOS Tools don't generate C code")
        return {}
    for key1, value1 in CanTrcv1145_config_dict.items():
        if key1 == "DefinitionRef":
            continue

        if value1["DefinitionRef"] == '/AUTOSAR/EcucDefs/CanTrcv1145/CanTrcvGeneral':
            CanTrcv1145_Genernal_dict = get_cantrcv1145_general_dict(value1)
        elif value1["DefinitionRef"] == '/AUTOSAR/EcucDefs/CanTrcv1145/CanTrcvConfigSet':
            CanTrcv1145_ConfigSet_dict = get_cantrcv1145_configset_dict(value1)

    spi_channel_prefix, spi_sequence_prefix = get_spi_prefix(sys_config)

    input_dict = {
        "CanTrcv1145_Genernal": CanTrcv1145_Genernal_dict,
        "CanTrcv1145_ConfigSet_dict": CanTrcv1145_ConfigSet_dict,
        "CanTrcvChannel": CanTrcv1145_ConfigSet_dict["CanTrcvChannel"],
        "spi_channel_prefix": spi_channel_prefix,
        "spi_sequence_prefix": spi_sequence_prefix,
    }

    return input_dict



def get_cantrcv1145_general_dict(data:dict) -> dict:
    ret_dict = dict.fromkeys([
        "CanTrcvDevErrorDetect", "CanTrcvGetVersionInfo", "CanTrcvSPICommRetries", \
        "CanTrcvSPICommTimeout", "CanTrcvWaitCount", "CanTrcvWakeUpSupport", \
        "CanTrcvUserConfigFile", "CanTrcvIndex", "CanTrcvMainFunctionPeriod", \
        "CanTrcvWaitTime", "CanTrcvWaitTimeSupport", "CanTrcvTimerType", "CanTrcvSafeBswChecks"
    ])

    ret_dict["CanTrcvWaitTimeSupport"] = 'STD_OFF'

    for key, value in data.items():
        if key == "DefinitionRef":
            continue

        if key == "CanTrcvDevErrorDetect":
            ret_dict["CanTrcvDevErrorDetect"] = change_boolean(value["Value"])
        elif key == "CanTrcvGetVersionInfo":
            ret_dict["CanTrcvGetVersionInfo"] = change_boolean(value["Value"])
        elif key == "CanTrcvSPICommRetries":
            ret_dict["CanTrcvSPICommRetries"] = int(0)
        elif key == "CanTrcvSPICommTimeout":
            ret_dict["CanTrcvSPICommTimeout"] = int(0)
        elif key == "CanTrcvWaitCount":
            ret_dict["CanTrcvWaitCount"] = value["Value"]
        elif key == "CanTrcvWakeUpSupport":
            if value["Value"] == 'CANTRCV_WAKEUP_BY_POLLING':
                ret_dict["CanTrcvWakeUpSupport"] = 'CANTRCV_TJA1145_WAKEUP_BY_POLLING'
            else:
                ret_dict["CanTrcvWakeUpSupport"] = 'CANTRCV_TJA1145_WAKEUP_NOT_SUPPORTED'
        elif key == "CanTrcvIndex":
            ret_dict["CanTrcvIndex"] = int(value["Value"])
        elif key == "CanTrcvMainFunctionPeriod":
            ret_dict["CanTrcvMainFunctionPeriod"] = int(value["Value"]) * 1000
        elif key == "CanTrcvWaitTime":
            ret_dict["CanTrcvWaitTime"] = int(value["Value"])
            if ret_dict["CanTrcvWaitTime"] == 0:
                ret_dict["CanTrcvWaitTimeSupport"] = 'STD_OFF'
            else:
                ret_dict["CanTrcvWaitTimeSupport"] = 'STD_ON'
        elif key == "CanTrcvTimerType":
            ret_dict["CanTrcvTimerType"] = ""
            pass
        if key == "CanTrcvSafeBswChecks":
            ret_dict["CanTrcvSafeBswChecks"] = change_boolean(value["Value"])

    return ret_dict


def get_cantrcv1145_configset_dict(data:dict) -> dict:
    ret_dict = dict.fromkeys([
        "CanTrcvSPICommRetries", "CanTrcvSPICommTimeout", "CanTrcvChannel", \
        "hwPnSupport", "pnEnabled", "verifyData", \
        "bussErrFlag", "fdTolerance", "wakeuUpByBusUsed", \
        "spiSynchronous", "usedExtendedWakeUpSrc",
    ])
    All_CanTrcvChannels_dict = {}
    for key, value in data.items():
        if key == "DefinitionRef":
            continue

        if key == "CanTrcvSPICommRetries":
            ret_dict["CanTrcvSPICommRetries"] = int(0)
        elif key == "CanTrcvSPICommTimeout":
            ret_dict["CanTrcvSPICommTimeout"] = int(0)
        elif value["DefinitionRef"] == "/AUTOSAR/EcucDefs/CanTrcv1145/CanTrcvConfigSet/CanTrcvChannel":
            cantrcv_channel = get_single_cantrcvchannel_dict(value)
            All_CanTrcvChannels_dict[key] = cantrcv_channel
        else:
            pass

    hwPnSupport = "STD_OFF"
    pnEnabled = "STD_OFF"
    verifyData = "STD_OFF"
    bussErrFlag = "STD_OFF"
    fdTolerance = "STD_OFF"
    wakeuUpByBusUsed = "STD_OFF"
    spiSynchronous = "STD_OFF"
    usedExtendedWakeUpSrc = "STD_OFF"

    for key1, value1 in All_CanTrcvChannels_dict.items():
        for key2, value2 in value1.items():
            if key2 == "CanTrcvHwPnSupport" and value2 == 'TRUE':
                hwPnSupport = "STD_ON"

            if key2 == "CanTrcvFdTolerance" and value2 == 'TRUE':
                fdTolerance = "STD_ON"

            if key2 == "CanTrcvWakeupByBusUsed" and value2 == 'TRUE':
                wakeuUpByBusUsed = "STD_ON"

            if key2 == "CanTrcvPartialNetwork":
                for key3, value3 in value2.items():
                    if key3 == "CanTrcvBusErrFlag" and value3 == "STD_ON":
                        bussErrFlag = "STD_ON"
                    if key3 == "CanTrcvPnEnabled" and value3 == "TRUE":
                        pnEnabled = "STD_ON"

            if key2 == "CanTrcvSpiSequence":
                for key3, value3 in value2.items():
                    if key3 == "CanTrcvSpiAccessSynchronousLMNList":
                        if "STD_ON" in value3:
                            spiSynchronous = "STD_ON"

            if (key2 == "CanTrcvPorWakeupSourceRefUsed" and value2 == "STD_ON") or \
                (key2 == "CanTrcvSyserrWakeupSourceRefUsed" and value2 == "STD_ON"):
                usedExtendedWakeUpSrc = "STD_ON"

    ret_dict["CanTrcvChannel"] = All_CanTrcvChannels_dict

    ret_dict["hwPnSupport"] = hwPnSupport
    ret_dict["pnEnabled"] = pnEnabled
    if pnEnabled == "STD_ON" and hwPnSupport == "STD_ON":
        verifyData = "STD_ON"
    else:
        verifyData = "STD_OFF"
    ret_dict["verifyData"] = verifyData

    ret_dict["fdTolerance"] = fdTolerance
    ret_dict["wakeuUpByBusUsed"] = wakeuUpByBusUsed
    ret_dict["bussErrFlag"] = bussErrFlag
    ret_dict["spiSynchronous"] = spiSynchronous
    ret_dict["usedExtendedWakeUpSrc"] = usedExtendedWakeUpSrc

    return ret_dict

def get_single_cantrcvchannel_dict(data:dict) -> dict:
    global  spiChannel_sorted_dict
    global  spiJob_sorted_dict
    global  spiSequence_sorted_dict
    global  spiChannel_sorted_index_dict
    global  spiJob_sorted_index_dict
    global  spiSequence_sorted_index_dict

    ret_dict = dict.fromkeys([
        "CanTrcvChannelUsed", "CanTrcvControlsPowerSupply", "CanTrcvHwPnSupport", \
        "CanTrcvWakeupByBusUsed", "CanTrcvEnablePNMD", "CanTrcvFdTolerance", \
        "CanTrcvChannelId", "CanTrcvMaxBaudrate", "CanTrcvInitState", \
        "CanTrcvWakeupSourceRef", "CanTrcvPorWakeupSourceRef", "CanTrcvSyserrWakeupSourceRef", \
        "CanTrcvPorWakeupSourceRefUsed", "CanTrcvSyserrWakeupSourceRefUsed", \
        "CanTrcvIcuChannelRef", "CanTrcvSpiSequence", "CanTrcvPartialNetwork", \
        "CanTrcvFrameControl", "SpiChannelRefList"
    ])
    ret_dict["CanTrcvPorWakeupSourceRefUsed"] = 'STD_OFF'
    ret_dict["CanTrcvSyserrWakeupSourceRefUsed"] = 'STD_OFF'
    ret_dict["SpiChannelRefList"] = []
    ret_dict["CanTrcvInitState"] = 'CANTRCV_TJA1145_OP_MODE_NORMAL'

    spiChannelRef_All_list = []

    cantrcvSpiSequence_dict = {}
    canTrcvPartialNetwork_dict = {}
    for key1, value1 in data.items():
        if key1 == "DefinitionRef":
            continue

        if key1 == "CanTrcvChannelUsed":
            if value1["Value"] == True:
                ret_dict["CanTrcvChannelUsed"] = 'TRUE'
            else:
                ret_dict["CanTrcvChannelUsed"] = 'FALSE'
        elif key1 == "CanTrcvControlsPowerSupply":
            ret_dict["CanTrcvControlsPowerSupply"] = "STD_OFF"
        elif key1 == "CanTrcvHwPnSupport":
            if value1["Value"] == True:
                ret_dict["CanTrcvHwPnSupport"] = 'TRUE'
            else:
                ret_dict["CanTrcvHwPnSupport"] = 'FALSE'
        elif key1 == "CanTrcvWakeupByBusUsed":
            if value1["Value"] == True:
                ret_dict["CanTrcvWakeupByBusUsed"] = 'TRUE'
            else:
                ret_dict["CanTrcvWakeupByBusUsed"] = 'FALSE'
        elif key1 == "CanTrcvEnablePNMD":
            if value1["Value"] == True:
                ret_dict["CanTrcvEnablePNMD"] = int(1)
            else:
                ret_dict["CanTrcvEnablePNMD"] = int(0)
        elif key1 == "CanTrcvFdTolerance":
            if value1["Value"] == True:
                ret_dict["CanTrcvFdTolerance"] = 'TRUE'
            else:
                ret_dict["CanTrcvFdTolerance"] = 'FALSE'
        elif key1 == "CanTrcvChannelId":
            ret_dict["CanTrcvChannelId"] = value1["Value"]
        elif key1 == "CanTrcvMaxBaudrate":
            ret_dict["CanTrcvMaxBaudrate"] = value1["Value"]
        elif key1 == "CanTrcvInitState":
            if checkIsNotNone(value1["Value"]):
              if value1["Value"] == "CANTRCV_OP_MODE_NORMAL":
                ret_dict["CanTrcvInitState"] = "CANTRCV_TJA1145_OP_MODE_NORMAL"
              elif value1["Value"] == "CANTRCV_OP_MODE_STANDBY":
                ret_dict["CanTrcvInitState"] = "CANTRCV_TJA1145_OP_MODE_STANDBY"
              elif value1["Value"] == "CANTRCV_OP_MODE_SLEEP":
                ret_dict["CanTrcvInitState"] = "CANTRCV_TJA1145_OP_MODE_SLEEP"
        elif key1 == "CanTrcvWakeupSourceRef":
            if checkIsNotNone(value1["ValueRef"]):
                ret_dict["CanTrcvWakeupSourceRef"] = value1["ValueRef"].split('/')[-1]
            else:
                ret_dict["CanTrcvWakeupSourceRef"] = '0'
        elif key1 == "CanTrcvPorWakeupSourceRef":
            if checkIsNotNone(value1["ValueRef"]):
                ret_dict["CanTrcvPorWakeupSourceRef"] = value1["ValueRef"].split('/')[-1]
                ret_dict["CanTrcvPorWakeupSourceRefUsed"] = 'STD_ON'
            else:
                ret_dict["CanTrcvPorWakeupSourceRef"] = '0'
        elif key1 == "CanTrcvSyserrWakeupSourceRef":
            if checkIsNotNone(value1["ValueRef"]):
                ret_dict["CanTrcvSyserrWakeupSourceRef"] = value1["ValueRef"].split('/')[-1]
                ret_dict["CanTrcvSyserrWakeupSourceRefUsed"] = 'STD_ON'
            else:
                ret_dict["CanTrcvSyserrWakeupSourceRef"] = '0'
        else:
            pass

    spiChannelRef_noDuplicatelist = list(set(spiChannelRef_All_list))
    spiChannelRef_All_Sorted_list = []

    for chnlIndex, chnlAttr in spiChannel_sorted_dict.items():
        for chnlRef in spiChannelRef_noDuplicatelist:
            if chnlRef == chnlAttr["spiChannelName"]:
                spiChannelRef_All_Sorted_list.append(chnlRef)
                break

    ret_dict["CanTrcvSpiSequence"] = cantrcvSpiSequence_dict
    ret_dict["CanTrcvPartialNetwork"] = canTrcvPartialNetwork_dict
    ret_dict["SpiChannelRefList"] = spiChannelRef_All_Sorted_list

    CanTrcvFrameControl = 0
    CanTrcvFrameControl |= 8
    CanTrcvFrameControl |= 0
    CanTrcvFrameControl |= 0
    ret_dict["CanTrcvFrameControl"] = CanTrcvFrameControl
    return ret_dict

